package cn.itsource.user.service.impl;

import cn.itsource.basic.constant.PetHomeConstant;
import cn.itsource.basic.util.HttpClientUtils;
import cn.itsource.basic.util.MD5Utils;
import cn.itsource.basic.util.StrUtils;
import cn.itsource.user.domain.LoginInfo;
import cn.itsource.user.domain.User;
import cn.itsource.user.domain.WechatUser;
import cn.itsource.user.domain.dto.UserDto;
import cn.itsource.user.mapper.LoginInfoMapper;
import cn.itsource.user.mapper.UserMapper;
import cn.itsource.user.mapper.WechatMapper;
import cn.itsource.user.service.IWechatService;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class WechatServiceImpl implements IWechatService {
    @Autowired
    private WechatMapper wechatMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private LoginInfoMapper loginInfoMapper;
    @Autowired
    private UserMapper userMapper;

    @Override
    public Map<String, Object> handleCallBack(String code) {
        //获取tokenurl地址
        String tokenUrl = PetHomeConstant.TOKENURL.replace("APPID", PetHomeConstant.APPID)
                .replace("SECRET", PetHomeConstant.SECRET)
                .replace("CODE", code);
        //通过token获取资源
        String strJson = HttpClientUtils.httpGet(tokenUrl);
        //把json字符串转化为json对象
        JSONObject jsonObject = JSONObject.parseObject(strJson);
        //获取openid微信唯一标识
        String openid = jsonObject.getString("openid");
        //获取access_token
        String access_token = jsonObject.getString("access_token");
        //获取unionid
        String unionid = jsonObject.getString("unionid");
        //通过access_token和openid获取资源信息
        String userInfoUrl = PetHomeConstant.USERINFOURL.replace("ACCESS_TOKEN", access_token)
                .replace("OPENID", openid);
        //java发送请求获取用户信息
        String userJson = HttpClientUtils.httpGet(userInfoUrl);
        //把微信用户字符串转化为json对象
        JSONObject jsonUser = jsonObject.parseObject(userJson);
        //通过openid查询是否微信用户数据库表
        WechatUser wechatUser = wechatMapper.findByOpenid(openid);
        HashMap<String, Object> map = new HashMap<>();
        //判断该微信用户是否存在
        if(wechatUser==null){//不存在保存到数据库
            WechatUser user = new WechatUser();
            String nickname = jsonUser.getString("nickname");
            //设置openid
            user.setOpenid(openid);
            //设置用户名
            user.setNickname(jsonUser.getString("nickname"));
            //设置unionid
            user.setUnionid(unionid);
            //设置性别
            user.setSex(jsonUser.getBoolean("sex"));
            //设置头像
            user.setHeadimgurl(jsonUser.getString("headimgurl"));
            //设置地址
            user.setAddress(jsonUser.getString("province")+" "+jsonUser.getString("city"));
            //保存在微信用户表中
            wechatMapper.save(user);
            //跳转到绑定界面
            map.put("openid", openid);
            return map;
        }else{
            LoginInfo loginInfo = wechatUser.getLoginInfo();
            if(loginInfo==null){//跳转到绑定页面
                map.put("openid", openid);
                return map;
            }else{
                //证明之前已经绑定过了，直接跳转到前台首页
                String token = UUID.randomUUID().toString();
                redisTemplate.opsForValue().set(token, loginInfo,30, TimeUnit.MINUTES);
                map.put("token", token);
                map.put("loginUser", loginInfo);
                return map;
            }
        }

    }

    @Override
    public Map<String, Object> binder(UserDto userDto) {
        //验证信息
        checkMsg(userDto);
        //通过用户名和类型，查找登录用户信息
        userDto.setUsername(userDto.getPhone());
        LoginInfo loginInfo = loginInfoMapper.findByUserDto(userDto);
        if(loginInfo==null){//该用户没注册过
            //将用户信息转化为登录用户
             loginInfo=userDto2LoginInfo(userDto);
            //保存loginInfo
            loginInfoMapper.save(loginInfo);
            //将登录用户转化为user对象
           User user= loginInfo2User(loginInfo);
           //保存用户
            userMapper.save(user);
        }
        //将登录用户表与微信用户表绑定
        wechatMapper.binder(loginInfo.getId(),userDto.getOpenid());
        //登录成功
        Map<String, Object> map= new HashMap<>();
        String token = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(token, loginInfo);
        map.put("token",token);
        map.put("loginUser",loginInfo);
        return map;
    }

    private User loginInfo2User(LoginInfo loginInfo) {
        User user = new User();
        BeanUtils.copyProperties(loginInfo, user);
        user.setLoginInfo(loginInfo);
        //设置用户状态为正常
        user.setState(PetHomeConstant.OK);
        return user;
    }

    //将用户信息转化为登录用户信息
    private LoginInfo userDto2LoginInfo(UserDto userDto) {
        LoginInfo loginInfo = new LoginInfo();
        loginInfo.setUsername(userDto.getPhone());
        loginInfo.setPhone(userDto.getPhone());
        loginInfo.setSalt(StrUtils.getRandomString(4));
        loginInfo.setType(userDto.getType());
        loginInfo.setPassword(MD5Utils.encrypByMd5(loginInfo.getPhone()+loginInfo.getSalt()));
        return loginInfo;
    }

    private void checkMsg(UserDto userDto) {
        //判断信息是否完整
        if(StringUtils.isEmpty(userDto.getPhone())||StringUtils.isEmpty(userDto.getCode())
                ||userDto.getType()==null){
            throw new RuntimeException("请填写完整信息");
        }
        String oldCode = (String) redisTemplate.opsForValue().get(PetHomeConstant.BINDER_VERIFICATION_CODE + ":" + userDto.getPhone());
        if(oldCode==null){//
            throw new RuntimeException("你的验证码已经过期");
        }
        if(!oldCode.split(":")[0].toLowerCase().equals(userDto.getCode().toLowerCase())){
            throw new RuntimeException("你的验证码不正确");
        }
    }
}
